using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;

namespace GPSNav.NET
{
	public class Utils
	{


		public static GraphicsPath MakeTextOnPath(GraphicsPath gp, string text)
		{

			GraphicsPath ret = new GraphicsPath();
			if (gp == null || gp.PointCount <= 1 || (gp.PointCount ) <= 1)
				return ret;

			PointF [] pcts = new PointF [gp.PointCount];
			Array.Copy(gp.PathPoints, 0, pcts, 0, gp.PointCount);
			
			return MakeTextOnPath(pcts, 0, text, FontFamily.GenericMonospace, 0, 12, 0, 0);
			
		}



		public static GraphicsPath MakeTextOnPath(PointF [] points, string text)
		{

			return MakeTextOnPath(points, 0, text, FontFamily.GenericMonospace, 0, 12, 0, 0);
		}



		public static GraphicsPath MakeTextOnPath(PointF [] pcts, int startIndex, string text, FontFamily ff, FontStyle fs, float emSize, float emSpace, float pathOffset)
		{

			GraphicsPath ret = new GraphicsPath();

			if (startIndex < 0)
				startIndex = 0;
			if (pcts == null || pcts.Length <= startIndex || (pcts.Length - startIndex) <= 1)
				return ret;

			int style = (int) fs;
			double [] totlens = new double [pcts.Length];
			double tlen = 0;
			totlens [0] = 0;
			for (int i = 0; i < pcts.Length - 1; i++)
			{
				double cl = Math.Sqrt(Math.Pow(pcts [i + 1].X - pcts [i].X, 2) + Math.Pow(pcts [i + 1].Y - pcts [i].Y, 2));
				tlen += cl;
				totlens [i + 1] = tlen;
			}


			double sl = 0;
			string t = text;
			string c;

			PointF p, np;
			double emWidth = 0;

			for (int k = 0; k < t.Length; k++)
			{

				if (sl > tlen)
				{
					break;
				}

				c = t.Substring(k, 1);

				int i;
				for (i = 1; i < totlens.Length - 1; i++)
				{
					if (totlens [i - 1] <= sl && totlens [i] >= sl)
					{
						break;
					}
				}
				i--;



				p = pcts [i];
				np = pcts [i + 1];

				double u = Math.Atan2(np.X - p.X, np.Y - p.Y);
				double cl = sl - totlens [i];
				float uu = 90 - (float) ((u * 180) / Math.PI);



				p.X += (float) (cl * Math.Sin(u));
				p.Y += (float) (cl * Math.Cos(u));
				Matrix m = new Matrix();
				if (pathOffset != 0.0f)
				{
					p.X = p.X - (float) (pathOffset * Math.Sin(Math.PI / 2 + u));
					p.Y = p.Y - (float) (pathOffset * Math.Cos(Math.PI / 2 + u));
				}
				m.Rotate(uu, MatrixOrder.Append);
				m.Translate(p.X, p.Y, MatrixOrder.Append);





				GraphicsPath gg = new GraphicsPath();
				if (c == " ")
				{
					gg.AddString("_", ff, style, emSize, PointF.Empty, StringFormat.GenericDefault);
					emWidth = 1.1f * gg.GetBounds().Width;
					gg.Flatten(m);
				}
				else
				{
					gg.AddString(c, ff, style, emSize, PointF.Empty, StringFormat.GenericDefault);
					emWidth = 1.1f * gg.GetBounds().Width;
					gg.Flatten(m);
					ret.AddPath(gg, false);
				}
				gg.Dispose();
				m.Dispose();

				sl += emWidth;
				sl += emSpace;

			}
			return ret;
		}


	}
}
